package gazzera.swing.browse;

import gazzera.gui.messages.*;
import gazzera.node.core.*;
import gazzera.swing.*;
import gazzera.swing.browse.items.*;
import gazzera.swing.model.*;
import gazzera.utils.*;

import java.util.*;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;


public class BrowseTree extends JTree implements TreeWillExpandListener, TreeSelectionListener // implements TreeModel
{
	NetworkItem root;
	//List<TreeModelListener> listeners = new ArrayList<TreeModelListener>();
	DefaultTreeModel m;
	Gazzera g;
	
	private Map<String, Item> activeSearches = new HashMap<String, Item>();
	
	public BrowseTree(Gazzera g)
	{
		super();
		this.g = g;
		setShowsRootHandles(true);
		addTreeSelectionListener(this);
		getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
		collapseRow(0);
		
		addTreeWillExpandListener(this);
		
		root = new NetworkItem();
		/*
		root.children.add(new UserItem());
		root.children.add(new UserItem());
		Item folder = new FolderItem("Folder");
		root.children.get(0).children.add(folder);
		folder.children.add(new FileItem());
		folder.children.add(new FileItem());
		folder.children.add(new FileItem());
		folder.children.add(new FileItem());
		*/
		m = new DefaultTreeModel(root);
		setModel(m);
		setCellRenderer(new MyRenderer());
		
	}
	
	
	
	
	
	@Override
	public void valueChanged(TreeSelectionEvent e)
	{
		Item node = (Item) getLastSelectedPathComponent();
		loadItem(node);

		System.out.println("Selected: " + node);
		if (node instanceof FolderItem)
		{
			
			FolderItem i = (FolderItem) node;
			/*
			if (i.files == null)
			{
				i.files = new FileTable();
				i.files.add(new RemoteFile(Hash.EMPTY, "prova.avi", i.id));
				// start request!
			}
			*/
			g.browseFileTable.setModel(i.files);
		}
	    
	}





	@Override
	public void treeWillCollapse(TreeExpansionEvent arg0) throws ExpandVetoException
	{
	    
	    
	}



	@Override
	public void treeWillExpand(TreeExpansionEvent e) throws ExpandVetoException
	{
		Item i = (Item)e.getPath().getLastPathComponent();
		loadItem(i);
		
		
	}





	private void loadItem(Item i)
	{
		if(i instanceof LoadableItem)
		{
			if(!((LoadableItem)i).isLoaded())
			{
				//if ( (i.getChildCount() == 1) && (i.getChildAt(0) instanceof LoadingItem)) 
				
					System.out.println("START LOADING");
					UserItem u;
					String folderId;
					if (i instanceof UserItem)
					{
						// the user was expanded
						u = (UserItem)i;
						folderId = ""; // ask for the root
						u.loaded = true;
					}
					else
					{
						// a folder was expanded, search for the user:
						FolderItem f = (FolderItem)i;
						Item p = (Item)i.getParent();
						while((p!=null) && (! (p instanceof UserItem)))
						{
							System.out.println("child of: "+p);
							p = (Item)p.getParent();
						}
						if(p==null) throw new RuntimeException("Folder to load without user ?!");
						u = (UserItem)p;
						folderId = f.fullname;
						
						f.files = new FileTableModel();
					}
					activeSearches.put(u.hash+""+folderId, i);
					g.gui.pass(new GuiStartBrowseSearch(u.hash, folderId));
					
				}
			
		}
	}



	public void updateConnection(Connection c)
	{
	    boolean insert = c.onlineStatus == OnlineStatus.ONLINE;
	    for (int i = 0; i < root.getChildCount(); i++)
	    {
		UserItem u = (UserItem)root.getChildAt(i);
		if(u.hash == c.hash)
		{
		    if(!insert) 
		    {
			root.remove(u);
			m.nodesWereRemoved(root, new int[]{i}, new Object[]{u});
			//repaint();
		    }
		    return;
		}
	    }
	    if(insert)
	    {
			UserItem u = new UserItem(c.hash, c.nickname);
			root.add(u);
			u.add(new LoadingItem());
			m.nodesWereInserted(root, new int[]{root.getChildCount()-1});
		//repaint();
	    }
	}
	
	public void addFolder(String userHash, String parent,String folder,boolean hasSubfolder)
	{
		Item i = activeSearches.get(userHash+""+parent);
		FolderItem n = new FolderItem((Str.isEmpty(parent) ? "":parent+"/") +folder, folder);
		n.parent = parent;
		if (hasSubfolder)
		{
			n.add(new LoadingItem());
		}
		i.add(n);
		
		if(i.getChildAt(0) instanceof LoadingItem)
		{
			Item rem = (Item)i.getChildAt(0);
			i.remove(0);
			m.nodesWereRemoved(i, new int[]{0}, new Object[]{rem});
		}
		
		m.nodesWereInserted(i, new int[]{i.getChildCount()-1});
		
	}
	
	public void finished(String userHash, String parent)
	{
		Item i = activeSearches.get(userHash+""+parent);
		if(i.getChildCount() > 0)
		{
		if(i.getChildAt(0) instanceof LoadingItem)
		{
			Item rem = (Item)i.getChildAt(0);
			i.remove(0);
			m.nodesWereRemoved(i, new int[]{0}, new Object[]{rem});
		}		
		}
	}
	public void addFile(String userHash, String parent, FileID fileId, String name, long size)
	{
		Item i = activeSearches.get(userHash+""+parent);
		if(i instanceof FolderItem)
		{
			FolderItem n = (FolderItem)i;
			RemoteFile r = new RemoteFile(fileId, name, size, parent+"/"+name, userHash);
			n.files.add(r);
			n.files.fireTableRowsInserted(n.files.getRowCount()-1, n.files.getRowCount()-1);
			
		}
		
	}

	
}
